<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>瑞智停</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Microsoft YaHei", sans-serif; }
        body { background-color: #000; color: #fff; height: 100vh; display: flex; justify-content: center; align-items: center; }
        .container { width: 100%; max-width: 1200px; height: 90vh; display: flex; background-color: #121212; border-radius: 10px; overflow: hidden; box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); }
        .left-panel, .right-panel { flex: 1; padding: 20px; display: flex; flex-direction: column; }
        .left-panel { border-right: 1px solid #333; align-items: center; }
        .speed-info { text-align: center; margin-top: 20px;margin-bottom: 20px; }
        .speed-info h2 { font-size: 28px; margin-bottom: 15px; }
        .speed-value { font-size: 24px; display: flex; justify-content: center; align-items: baseline; }
        #speed { font-size: 40px; font-weight: bold; margin-right: 5px; }
        .unit { color: #aaa; }
        #canvas-container { width: 380px; height: 380px; position: relative; margin-top: 40px; }
        #radarCanvas { width: 100%; height: 100%; display: block; }
        #car-img { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 100px; height: auto; pointer-events: none; }
        .camera-view { flex: 2; background-color: #1a1a1a; border-radius: 8px; margin-bottom: 20px; display: flex; justify-content: center; align-items: center; overflow: hidden; }
        .camera-placeholder { color: #555; font-size: 18px; text-align: center; }
        #camera-feed { width: 100%; height: 100%; object-fit: cover; display: none; }
        .control-panel { flex: 1; display: flex; flex-direction: column; align-items: center; }
        .main-btn { width: 80%; padding: 15px; font-size: 18px; background-color: #0078d7; color: white; border: none; border-radius: 30px; cursor: pointer; margin-bottom: 20px; transition: all 0.3s ease; }
        .main-btn:hover { background-color: #0063b1; }
        .main-btn.searching { background-color: #d32f2f; animation: pulse 1.5s infinite; }
        @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(211, 47, 47, 0.7); } 70% { box-shadow: 0 0 0 10px rgba(211, 47, 47, 0); } 100% { box-shadow: 0 0 0 0 rgba(211, 47, 47, 0); } }
        .spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid white; border-top: 2px solid transparent; border-radius: 50%; animation: spin 1s linear infinite; margin-left: 8px; vertical-align: middle; }
        @keyframes spin { to { transform: rotate(360deg); } }
        .parking-spots { display: flex; justify-content: space-between; width: 100%; padding: 0 10px; }
        .spot-btn { flex: 1; margin: 0 10px; padding: 12px; font-size: 16px; background-color: #333; color: white; border: none; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; }
        .spot-btn:hover:not(.disabled) { background-color: #444; }
        .spot-btn.active { background-color: #4caf50; }
        .spot-btn.disabled { background-color: #333; opacity: 0.5; cursor: not-allowed; }
        #secret-code-display { position: fixed; left: 10px; bottom: 10px; font-family: monospace; font-size: 10px; color: rgba(255, 253, 253, 0.134); pointer-events: none; user-select: none; }
    </style>
</head>
<body>
<div class="container">
    <div class="left-panel">
        <div class="speed-info"><h2>瑞智停</h2><div class="speed-value"><span id="speed">0</span><span class="unit">m/s</span></div></div>
        <div id="canvas-container"><canvas id="radarCanvas"></canvas><img id="car-img" src="./car.png" alt="car" /></div>
    </div>
    <div class="right-panel">
        <div class="camera-view" id="camera-view"><div class="camera-placeholder">摄像头关闭</div><img id="camera-feed" src="" alt="车位照片" /></div>
        <div class="control-panel">
            <button id="find-spot-btn" class="main-btn">寻找车位</button>
            <div class="parking-spots">
                <button id="spot-1" class="spot-btn disabled">车位1</button>
                <button id="spot-2" class="spot-btn disabled">车位2</button>
                <button id="spot-3" class="spot-btn disabled">车位3</button>
            </div>
        </div>
    </div>
</div>
<div id="secret-code-display">11</div> <!-- 初始状态为11，这样第一次发送就不用输入了-->

<!-- [新增] 音频元素 -->
<audio id="audio-start-search" src="./video/小瑞去找车位啦.mp3" preload="auto"></audio>
<audio id="audio-found-spot" src="./video/小瑞找到车位啦.mp3" preload="auto"></audio>
<audio id="audio-start-parking" src="./video/小瑞开始停车啦.mp3" preload="auto"></audio>
<audio id="audio-parking-complete" src="./video/停车完毕.mp3" preload="auto"></audio>

<script>
    // --- 雷达图绘制代码 (保持不变) ---
    const canvas = document.getElementById('radarCanvas'), ctx = canvas.getContext('2d'), container = document.getElementById('canvas-container'), MAX_D = 35, DANGER = 20, WARNING = 25;
    let distances = [90,200,0,200,0,0];
    function resizeCanvas() { const size = container.clientWidth; canvas.width = size; canvas.height = size; }
    function drawRadar() {
        const cx = canvas.width/2, cy = canvas.height/2, r = Math.min(canvas.width/2, canvas.height/2) * 0.85, pulse = Math.sin(Date.now()*0.005)*8;
        ctx.clearRect(0,0,canvas.width,canvas.height); ctx.beginPath(); ctx.arc(cx, cy, r*0.7, 0, Math.PI*2); ctx.strokeStyle = 'rgba(50, 50, 50, 0.3)'; ctx.lineWidth = 1; ctx.stroke(); ctx.beginPath(); ctx.arc(cx, cy, r*0.5, 0, Math.PI*2); ctx.stroke();
        const sensors = [{x:cx, y:cy - r*0.4, sa:-130, ea:-50},{x:cx + r*0.4, y:cy - r*0.2, sa:-60, ea:0},{x:cx + r*0.4, y:cy + r*0.2, sa:0, ea:60},{x:cx, y:cy + r*0.4, sa:50, ea:130},{x:cx - r*0.4, y:cy + r*0.2, sa:120, ea:180},{x:cx - r*0.4, y:cy - r*0.2, sa:180, ea:240}];
        ctx.strokeStyle = 'rgba(100, 100, 100, 0.2)'; ctx.lineWidth = 1; sensors.forEach(s => { ctx.beginPath(); ctx.moveTo(cx, cy); ctx.lineTo(s.x, s.y); ctx.stroke(); });
        sensors.forEach((s,i) => {
            const d = distances[i], normalizedDistance = Math.min(d / MAX_D, 1), minRadius = r * 0.25, maxRadius = r * 0.55, ar = minRadius + normalizedDistance * (maxRadius - minRadius);
            let red, green, blue, glowSize;
            if (d < DANGER) { const t = d / DANGER; red = 255; green = Math.round(t * 100); blue = 68; glowSize = 20 + pulse; }
            else if (d < WARNING) { const t = (d - DANGER) / (WARNING - DANGER); red = 255; green = Math.round(195 + t * (196 - 195)); blue = Math.round(68 - t * 68); glowSize = 18 + pulse + t * 7; }
            else { const t = Math.min((d - WARNING) / (MAX_D - WARNING), 1); red = Math.round(255 - t * 255); green = 196; blue = Math.round(t * 118); glowSize = 25 + pulse; }
            const clr = `rgb(${red}, ${green}, ${blue})`, thickness = r*0.08, sa = s.sa * Math.PI/180, ea = s.ea * Math.PI/180;
            ctx.beginPath(); ctx.arc(s.x, s.y, ar, sa, ea); ctx.arc(s.x, s.y, ar - thickness, ea, sa, true); ctx.closePath(); const gradient = ctx.createRadialGradient(s.x, s.y, ar-thickness, s.x, s.y, ar); gradient.addColorStop(0, 'rgba(0,0,0,0)'); gradient.addColorStop(0.7, clr); gradient.addColorStop(1, clr); ctx.fillStyle = gradient; ctx.shadowColor = clr; ctx.shadowBlur = glowSize; ctx.fill(); ctx.shadowBlur = 0;
        });
        requestAnimationFrame(drawRadar);
    }
    window.addEventListener('resize', resizeCanvas);
    resizeCanvas(); drawRadar();

    // --- UI 交互逻辑 ---
    let isSearching = false, parkingInProgress = false, lastImage = null, foundSpot = false;
    const findBtn = document.getElementById('find-spot-btn');
    const spot1 = document.getElementById('spot-1');
    const speedEl = document.getElementById('speed');
    const cameraFeed = document.getElementById('camera-feed');
    const cameraPlaceholder = document.querySelector('.camera-placeholder');
    const secretCodeDisplay = document.getElementById('secret-code-display');
    let codeDigits = ['1', '1']; let isReplacingFirstDigit = true; // 默认为10，这样第一次发送就不用输入了
    let speedInterval = null; // [新增] 用于存储速度更新的定时器

    // [新增] 获取音频元素
    const audioStartSearch = document.getElementById('audio-start-search');
    const audioFoundSpot = document.getElementById('audio-found-spot');
    const audioStartParking = document.getElementById('audio-start-parking');
    const audioParkingComplete = document.getElementById('audio-parking-complete');

    // [新增] 随机更新速度值的函数
    function startRandomSpeedUpdates() {
        // 先清除之前可能存在的定时器
        if (speedInterval) {
            clearInterval(speedInterval);
        }
        
        // 每200ms更新一次速度值
        speedInterval = setInterval(() => {
            const randomSpeed = (Math.random() * (0.045 - 0.035) + 0.035).toFixed(3);
            speedEl.textContent = randomSpeed;
        }, 200);
    }

    // [新增] 停止速度值更新的函数
    function stopRandomSpeedUpdates() {
        if (speedInterval) {
            clearInterval(speedInterval);
            speedInterval = null;
        }
        // 恢复为0
        speedEl.textContent = "0";
    }
    
    document.addEventListener('keydown', (event) => {
        if (/^[0-9]$/.test(event.key)) {
            const newDigit = event.key;
            if (isReplacingFirstDigit) { codeDigits[0] = newDigit; } 
            else { codeDigits[1] = newDigit; }
            isReplacingFirstDigit = !isReplacingFirstDigit;
            secretCodeDisplay.textContent = codeDigits.join('');
        }
    });

    function showPlaceholder(text, fontSize = '18px') { cameraPlaceholder.style.display = 'block'; cameraPlaceholder.innerHTML = text; cameraPlaceholder.style.fontSize = fontSize; cameraFeed.style.display = 'none'; }
    function showImage(src) { cameraFeed.src = src; cameraFeed.style.display = 'block'; cameraPlaceholder.style.display = 'none'; }
    
    // [修改] '寻找车位' 按钮的点击事件，增加音频播放
    findBtn.addEventListener('click', () => {
        if (parkingInProgress) return;
        isSearching = !isSearching;
        findBtn.textContent = isSearching ? '停止寻找' : '寻找车位';
        findBtn.classList.toggle('searching', isSearching);
        if (isSearching) {
            showPlaceholder('寻找车位中<span class="spinner"></span>', '20px');
            audioStartSearch.play(); // [新增] 播放"小瑞去找车位啦.m4a"
            foundSpot = false; // 重置找到车位的状态
        } else {
            showPlaceholder('摄像头关闭');
            lastImage = null;
        }
        fetch('http://192.168.1.199/?action=' + (isSearching ? 'start_search' : 'stop_search'))
            .catch(e => console.error("无法连接到硬件设备以控制搜索:", e));
    });

    // --- [核心修改] WebSocket 通信 ---
    const socket = new WebSocket('ws://127.0.0.1:5000');

    socket.onopen = () => console.log("与本地服务器的WebSocket连接已建立。");
    socket.onerror = (error) => alert('无法连接到本地服务器！请确保 server.py 正在运行。');
    socket.onclose = () => console.log("与本地服务器的连接已断开。");

    // [核心修改] 监听来自服务器的"泊车完成"消息
    socket.onmessage = (event) => {
        const data = JSON.parse(event.data);
        if (data.status === 'parking_complete') {
            console.log("收到泊车完成标志位。");
            parkingInProgress = false;
            spot1.classList.remove('active');
            showPlaceholder('泊车完成！', '24px');
            audioParkingComplete.play(); // [新增] 播放"停车完毕.m4a"
            
            // [新增] 停止速度更新
            stopRandomSpeedUpdates();
        }
    };
    
    // [核心修改] "车位1"按钮的点击事件，通过WebSocket发送指令
    spot1.addEventListener('click', () => {
        if (spot1.classList.contains('disabled') || parkingInProgress) return;
        if (!socket || socket.readyState !== WebSocket.OPEN) {
            alert('与本地服务器的连接尚未就绪。');
            return;
        }

        parkingInProgress = true;
        spot1.classList.add('active');
        const code = codeDigits.join('');
        showPlaceholder(`<br>正在泊入车位...<span class="spinner"></span>`, '20px');
        
        // [修改] 开始持续更新速度值而不是只显示一次
        startRandomSpeedUpdates();
        
        audioStartParking.play(); // [新增] 播放"小瑞开始停车啦.m4a"

        socket.send(JSON.stringify({
            action: 'start_parking',
            params: code
        }));
    });

    // --- 与硬件的数据轮询，保持后台同步 ---
    setInterval(async () => {
        try {
            const res = await fetch('http://192.168.1.199/');
            const data = await res.json();

            isSearching = data.search === 1;
            distances = data.distances || distances;
            
            // [修改] 只有在非泊车过程中才更新来自硬件的速度值
            if (!parkingInProgress) {
                speedEl.textContent = data.speed.toFixed(2);
            }
            
            if (data.image) {
                lastImage = 'data:image/jpeg;base64,' + data.image;
            }

            // [新增] 找到车位时播放音频
            // 如果正在寻找，且之前没找到，现在找到了，则播放音频
            if (isSearching && !foundSpot && data.found === 1) {
                foundSpot = true; // 标记为已找到，防止重复播放
                console.log("找到车位！准备播放音频");
                
                // 确保音频元素已正确加载并尝试播放
                if (audioFoundSpot.readyState >= 2) {
                    audioFoundSpot.play()
                        .then(() => console.log("音频播放成功"))
                        .catch(err => console.error("音频播放失败:", err));
                } else {
                    console.log("音频尚未加载完成，重新加载");
                    audioFoundSpot.load();
                    setTimeout(() => {
                        audioFoundSpot.play()
                            .then(() => console.log("延迟后音频播放成功"))
                            .catch(err => console.error("延迟后音频播放失败:", err));
                    }, 1000);
                }
                
                // 如果有图片，显示图片
                if (lastImage) {
                    showImage(lastImage);
                }
            }
            
            // 添加调试信息
            if (isSearching && data.found === 1 && !foundSpot) {
                console.log("硬件报告找到车位，但foundSpot为false");
            }

            // 当不处于泊车流程中时，UI完全由硬件数据决定
            if (!parkingInProgress) {
                findBtn.textContent = isSearching ? '停止寻找' : '寻找车位';
                findBtn.classList.toggle('searching', isSearching);
                spot1.classList.toggle('disabled', data.found !== 1);
                
                if ((!isSearching && lastImage) || (isSearching && foundSpot && lastImage)) {
                    showImage(lastImage);
                } else if (isSearching && !foundSpot) {
                    showPlaceholder('寻找车位中<span class="spinner"></span>', '20px');
                } else {
                    showPlaceholder('摄像头关闭');
                }
            }
        } catch (e) {
            // 静默处理轮询错误
        }
    }, 200);
</script>
</body>
</html>